<?php
class FunctionGameCenter{
	static function getAllGames(){
		$appid = DataGameManager::getAppID();
		$next_id = FunctionApp::getStaticKey($appid,"next_id" );
		$games = array();
		for($i = 1; $i < $next_id; $i++){
			$games[] = (self::readGameInfo($i));
		}
		return $games;
	}
	static function readGameInfo($gameid){
		$appid = DataGameManager::getAppID();
		$data = FunctionApp::getStaticKey($appid,"_games_" .$gameid);
		if($data != null) return DataGameInfo::swap(ByteBuffer::wrap( $data ) );
		return null;
	}
	static function writeGameInfo($gameid,$gameinfo_obj){
		$appid = DataGameManager::getAppID();
		FunctionApp::setStaticKey($appid,"_games_" .$gameid,$gameinfo_obj->getBinary());
	}
	static function readUserGames($userid){
		$appid = DataGameManager::getAppID();
		$data = FunctionApp::getUserKey($appid,$userid,"_games_" );
		if($data != null) return DataUserGames::swap(ByteBuffer::wrap( $data ) );
		return new DataUserGames();
	}
	static function writeUserGames($userid,$usergames_obj){
		$appid = DataGameManager::getAppID();
		FunctionApp::setUserKey($appid,$userid,"_games_" ,$usergames_obj->getBinary());
	}
	static function readUserHighScore($gameid, $userid){
		$appid = DataGameManager::getAppID();
		$key = "_high_" .$gameid;
		$highscore = FunctionApp::getUserKey($appid,$userid,$key);
		return $highscore;
	}
	static function writeUserHighScore($gameid, $userid, $score){
		$appid = DataGameManager::getAppID();
		$key = "_high_" .$gameid;
		FunctionApp::setUserKey($appid,$userid,$key,$score);
	}
	static function readUserCurrentScore($gameid, $userid){
		$appid = DataGameManager::getAppID();
		$key = "_score_" .$gameid;
		$currscore = FunctionApp::getUserKey($appid,$userid,$key);
		$keytime = "_sctime_" .$gameid;
		$last_time = FunctionApp::getUserKey($gameid, $userid, $keytime);
		if(time()  - $last_time > 180 ){ 
			if(self::getRewardForTournament($gameid, $userid, $last_time, $currscore)){
				$key_tour = "_tward_" .$gameid;
				FunctionApp::incUserKey($appid, $userid, $key_tour);
			}
			$key_last = "_lscore_" .$gameid;
			$key_lasttime = "_lsctime_" .$gameid;
			$time = FunctionApp::getUserKey($appid,$userid,$keytime);
			FunctionApp::setUserKey($appid, $userid, $key_last, $currscore);
			FunctionAPP::setUserKey($appid, $userid, $key_lasttime, $time);
		}
		return $currscore;
	}
	static function writeUserCurrentScore($gameid, $userid, $score){
		$appid = DataGameManager::getAppID();
		$curr_time = time() ;
		$key = "_score_" .$gameid;		
		$keytime = "_sctime_" .$gameid;
		$last_time = FunctionApp::getUserKey($gameid, $userid, $keytime);
		if($curr_time - $last_time > 180 ){ 
			$currscore = FunctionApp::getUserKey($appid,$userid,$key);
			$currtime = FunctionApp::getUserKey($appid,$userid,$keytime);
			if(self::getRewardForTournament($gameid, $userid, $currtime, $currscore)){  
				$key_tour = "_tward_" .$gameid;
				FunctionApp::incUserKey($appid, $userid, $key_tour);
			}
			$key_last = "_lscore_" .$gameid;
			$key_lasttime = "_lsctime_" .$gameid;
			FunctionApp::setUserKey($appid, $userid, $key_last, $currscore);
			FunctionAPP::setUserKey($appid, $userid, $key_lasttime, $currtime);
		}
		FunctionApp::setUserKey($appid,$userid,$key,$score);
		FunctionApp::setUserKey($appid,$userid,$keytime,$curr_time);
		$checktime = FunctionApp::getUserKey($appid,$userid,$keytime);
		$checkscore = FunctionApp::getUserKey($appid,$userid,$key);
	}
	static function readUserRequests($userid){
		$appid = DataGameManager::getAppID();
		$data = FunctionApp::getUserKey($appid,$userid,"_request_" );
		if($data != null) return DataUserRequests::swap(ByteBuffer::wrap( $data ) );
		return new DataUserRequests();
	}
	static function writeUserRequests($userid,$request_obj){
		$appid = DataGameManager::getAppID();
		FunctionApp::setUserKey($appid,$userid,"_request_" ,$request_obj->getBinary());
	}
	static function readLeaderBoard($gameid,$boardid){
		$appid = DataGameManager::getAppID();
		$key = "board_" . $gameid.'_'. $boardid;
		$data = FunctionApp::getStaticKey($appid, $key);
		if($data != null){
			return DataLeaderBoard::swap(ByteBuffer::wrap( $data ) );
		}
		return null;
	}
	static function writeLeaderBoard($gameid, $boardid, $board){
		$appid = DataGameManager::getAppID();
		$key = "board_" . $gameid.'_'. $boardid;
		FunctionApp::setStaticKey($appid,$key, $board->getBinary());
	}
	static private function getRewardForTournament($gameid, $userid, $time, $score){
		$appid = DataGameManager::getAppID();
		$current_tour = (time()  -  (time()  % 180 ))/ 180 ;
		$check_tour = ($time - ($time % 180 ))/ 180 ;
		if($current_tour - $check_tour >= 2)return false;
		$friends = FunctionSession::getFriends();
		if($friends != null){
			$key = "_score_" .$gameid;		
			$keytime = "_sctime_" .$gameid;
			$key_last = "_lscore_" .$gameid;
			$key_lasttime = "_lsctime_" .$gameid;
			$fids = $friends->getFriendsID();
			if(!is_array($fids) || count($fids) < 1 ) return false;
			$reward = true;
			foreach($fids as $fid){
				$ftime = FunctionApp::getUserKey($appid, $fid, $keytime);
				if($ftime == null)continue;
				$fturn = ($ftime - ($ftime % 180 ))/ 180 ;
				$score_key = $key;
				if($fturn != $check_tour){
					$ftime = FunctionApp::getUserKey($appid, $fid, $key_lasttime);
					if($ftime == null) continue;
					$fturn = ($ftime - ($ftime % 180 ))/ 180 ;
					$score_key = $key_last;
					if($fturn != $check_tour) continue;
				}
				$fscore = FunctionApp::getUserKey($appid, $fid, $score_key);
				if($fscore > $score){
					$reward = false;
					break;  
				}
			}
			return $reward;
		}
		return false;
	}
	static function getTournamentWithFriendsList($gameid, $userid, $fids){
		$appid = DataGameManager::getAppID();
		$key = "_score_" .$gameid;		
		$keytime = "_sctime_" .$gameid;
		$key_last = "_lscore_" .$gameid;
		$key_lasttime = "_lsctime_" .$gameid;
		$time = FunctionApp::getUserKey($appid, $userid, $keytime);
		$score = FunctionApp::getUserKey($appid, $userid, $key);
		if($time == null || $score == null){
			return null;
		}
		$last_tour_key = "_tlastid_" .$gameid;
		$lasttour = FunctionApp::getUserKey($appid, $userid, $last_tour_key);
		$current_tour = (time()  -  (time()  % 180 ))/ 180 ;
		$check_tour = ($time - ($time % 180 ))/ 180 ;
		if($current_tour - $check_tour >= 2){
			return null;
		}
		if($lasttour != null && $check_tour <= $lasttour)return null;
		if(!is_array($fids) || count($fids) < 1 ) return null;
		$result = array(
			"tourid"=>$check_tour,
			"curtourid"=>$current_tour,
			"time"=>$time,
			"curtime"=> time() ,
			"reward"=>true, 
			"list"=>array());
		$uname = unpack('C*', FunctionData::getDisplayNameOfId($userid) ) ;
		$result["list"][] = array("id"=>$userid,"score"=>$score, "name"=>$uname);
		foreach($fids as $fid){
			$fname = unpack('C*', FunctionData::getDisplayNameOfId($fid) ) ;
			$ftime = FunctionApp::getUserKey($appid, $fid, $keytime);
			if($ftime == null){
				$result["list"][] = array("id"=>$fid, "score"=>0, "name"=>$fname);
				continue;
			}
			$fturn = ($ftime - ($ftime % 180 ))/ 180 ;
			$score_key = $key;
			if($fturn != $check_tour){
				$ftime = FunctionApp::getUserKey($appid, $fid, $key_lasttime);
				if($ftime == null){
					$result["list"][] = array("id"=>$fid, "score"=>0, "name"=>$fname);
					continue;
				}
				$fturn = ($ftime - ($ftime % 180 ))/ 180 ;
				$score_key = $key_last;
				if($fturn != $check_tour){
					$result["list"][] = array("id"=>$fid, "score"=>0, "name"=>$fname);
					continue;
				}
			}
			$fscore = FunctionApp::getUserKey($appid, $fid, $score_key);
			$result["list"][] = array("id"=>$fid, "score"=>$fscore,"name"=>$fname);
			if($fscore > $score){
				$result["reward"] = false;
				break;  
			}
		}
		return $result;
	}
	static function registeAGame($name,$description){
		$rs = new Result();
		$appid = DataGameManager::getAppID();
		$next_id = FunctionApp::getStaticKey($appid,"next_id" );
		if($next_id == null){
			$next_id = 1;
		}else{
			$next_id = 0 + $next_id;
		}
		FunctionApp::setStaticKey($appid,"next_id" ,$next_id + 1);
		FunctionApp::addStaticKey($appid,"_games_" .$next_id);
		FunctionApp::addUserKey($appid,"_high_" .$next_id);
		FunctionApp::addUserKey($appid,"_score_" .$next_id);
		FunctionApp::addUserKey($appid,"_sctime_" .$next_id);
		FunctionApp::addUserKey($appid,"_lscore_" .$next_id);
		FunctionApp::addUserKey($appid,KEYINT_TOKEN_GAMECENTER_USER_SCORE_LASTTIME.$next_id);
		FunctionApp::addUserKey($appid,"_tward_" .$next_id);
		FunctionApp::addUserKey($appid,"_gtable_" .$next_id);
		$fbappid = FunctionData::registerAFacebookAppId();
		$game = new DataGameInfo();
		$game->setName($name);
		$game->setInfomation($description);
		$game->setFbAppId($fbappid);
		self::writeGameInfo($next_id,$game);
		$rs->return = true;
		$rs->addData("Message","Create game successfull");
		$rs->addData("Id",$next_id);
		$rs->addData("SecretKey",$game->getSecretKey());
		return $rs;
	}
	static function getGamesOfUser($userid){
		self::readUserGames($userid)->getGames();
	}
	static function addGameToUser($userid,$gameid){
		$games = self::readUserGames($userid);
		$games->addGame($gameid);
		self::writeUserGames($userid,$game);
	}
	static function getGamesRequestOfUser($userid){
		$requests = self::readUserRequests($userid);
		return $requests->getRequests();
	}
	static function addGameRequestToUser($userid_sender,$userid_receiver,$gameid,$type){
		$requests = self::readUserRequests($userid_receiver);
		$requests->addRequest($userid_sender,$gameid,$type);
		self::writeUserRequests($userid_receiver);
	}
	static function removeGameRequestOfUser($userid,$userid_sender,$gameid,$type){
		$request = self::readUserRequests($userid);
		$requests->removeRequest($userid_sender,$gameid,$type);
		self::writeUserRequests($userid);
	}
	static function createLeaderBoard($gameid, $board_title, $board_limit){
		{Error::getInstance() ->addError( 0 , "crateleader board:".$gameid."_".$board_title."_".$board_limit );} ;
		$gameinfo = self::readGameInfo($gameid);
		if($gameinfo != null){
			$appid = DataGameManager::getAppID();
			$id = $gameinfo->getNumOfLeaderBoard();
			$key = "board_" . $gameid.'_'. $id;
			{Error::getInstance() ->addError( 0 , "leaderboard id:".$id." key:".$key );} ;
			FunctionApp::addStaticKey($appid,$key);
			$gameinfo->addLeaderBoard(new LeaderBoardInfo($id,$board_title));
			$boardobj = new DataLeaderBoard($board_limit);
			self::writeLeaderBoard($gameid, $id, $boardobj);
			self::writeGameInfo($gameid,$gameinfo);
		}else{
			{Error::getInstance() ->addError( 0 , "game info null" );} ;
		}
	}
	static function putHighScore($gameid, $score, $ensure_key){
		$score = 0 + $score;
		if(Session::isLogin()){
			$game = self::readGameInfo($gameid);
			if($game != null){
				self::writeUserCurrentScore($gameid,Session::getID(),$score);
				$hscore = self::readUserHighScore($gameid,Session::getID());
				if($hscore == null || $hscore < $score){
					self::writeUserHighScore($gameid,Session::getID(),$score);
				}
				$secretkey = $game->getSecretKey();
				$userid = Session::getID();
				$hashstr = $gameid.$userid.$score.$secretkey;
				if(md5($hashstr) == $ensure_key){
					$boards = $game->getLeaderBoards();
					if(is_array($boards)){
						foreach($boards as $board){
							$boardid = $board->getID();
							$boardobj = self::readLeaderBoard($gameid, $boardid);
							if($boardobj != null){
								if($boardobj->putSocreTemp($userid, $score)){
									self::writeLeaderBoard($gameid, $boardid, $boardobj);
									return true;
								}else{
								}
							}else{
							}
						}
						return true;
					}else{
					}
				}else{
				}
			}else{
			}
		}else{
			{Error::getInstance() ->addError( 17  , "Please Login First" );} ;
		}
		return false;
	}
	static function putHighScoreOnBoard($gameid, $boardid, $score, $ensure_key){
		$score = 0 + $score;
		if(Session::isLogin()){
			$game = self::readGameInfo($gameid);
			if($game != null){
				self::writeUserCurrentScore($gameid,Session::getID(),$score);
				$hscore = self::readUserHighScore($gameid,Session::getID());
				if($hscore == null || $hscore < $score){
					self::writeUserHighScore($gameid,Session::getID(),$score);
				}
				$secretkey = $game->getSecretKey();
				$userid = Session::getID();
				$hashstr = $gameid.$userid.$boardid.$score.$secretkey;
				if(md5($hashstr) == $ensure_key){
					$boardobj = self::readLeaderBoard($gameid, $boardid);
					if($boardobj != null){
						if($boardobj->putScore($userid, $score)){
							self::writeLeaderBoard($gameid, $boardid, $boardobj);
							return true;
						}
					}else{
					}
				}else{
				}
			}else{
			}
		}else{
			{Error::getInstance() ->addError( 17  , "Please Login First" );} ;
		}
		return false;
	}
	static function getRequests($revision){
		if(Session::isLogin()){
			$requests = self::readUserRequests(SESSION::getID());
			if($requests->getRevision() != $revision){
				return $requests->getRequests();
			}
		}
		return null;
	}
	static function getRequestsOfGame($gameid, $revision){
		if(Session::isLogin()){
			$requests = self::readUserRequests(SESSION::getID());
			if($requests->getRevision() != $revision){
				$requests_list = $requests->getRequests();
				$rs_list = array();
				if(is_array($requests_list)){
					foreach($requests_list as $request){
						if($request->GameID == $gameid){
							$rs_list[] = $request;
						}
					}
				}
				return $rs_list;
			}
		}else{
			{Error::getInstance() ->addError( 17  , "Please login first" );} ;
		}
		return null;
	}
	static function getRequestsOfUser($identify){
		if(FunctionData::checkIdentifyValid($identify)){
			$id = FunctionData::getIDFromIdentify($identify);
			if($id >= 0){
				$requests = self::readUserRequests($id);
				return $requests->getRequests();
			}
		}
		return null;
	}
	static function putRequestToFriend($friend_id,$gameid,$type,$message){
		if(SESSION::isLogin()){
			if(FunctionSession::isFriend($friend_id)){
				$requests = self::readUserRequests($friend_id);
				$requests->addRequest(SESSION::getID(),$gameid,$type,$message);
				self::writeUserRequests($friend_id,$requests);
				return true;
			}else{
				{Error::getInstance() ->addError( 20  , "This Account is not a friend!" );} ;
				return false;
			}
		}
		{Error::getInstance() ->addError( 17  , "Please login first" );} ;
		return false;
	}
	static function putRequestFromUserToFriend($uid,$friend_id,$gameid,$type,$message){
		if(FunctionData::checkIDValid($uid)){
			if(FunctionSession::isFriendOfUserID($uid,$friend_id)){
				$requests = self::readUserRequests($friend_id);
				$requests->addRequest($uid,$gameid,$type,$message);
				self::writeUserRequests($friend_id,$requests);
			}else{
				{Error::getInstance() ->addError( 20  , "This Account is not a friend!" );} ;
				return false;
			}
		}else{
			{Error::getInstance() ->addError( 12  , "System error: identify not found" );} ;
		}
	}
	static function removeRequest($request_id,$gameid,$type){
		if(Session::isLogin()){
			$requests = self::readUserRequests(Session::getID());
			if($requests->removeRequest($request_id,$gameid,$type)){
				self::writeUserRequests(Session::getID(),$requests);
				return true;
			}
		}else{
			{Error::getInstance() ->addError( 12  , "System error: identify not found" );} ;
		}
		return false;
	}
	static function removeRequestOfUser($uid,$request_id,$gameid,$type){
		if(FunctionData::checkIDValid($uid)){
			$requests = self::readUserRequests($uid);
			if($requests->removeRequest($request_id,$gameid,$type)){
				self::writeUserRequests($uid,$requests);
				return true;
			}
		}else{
			{Error::getInstance() ->addError( 12  , "System error: account not found" );} ;
		}
		return false;
	}
	static function getTournamentOfUser($gameid, $userid){
		$appid = DataGameManager::getAppID();
		$key = "_score_" .$gameid;		
		$keytime = "_sctime_" .$gameid;
		$key_last = "_lscore_" .$gameid;
		$key_lasttime = "_lsctime_" .$gameid;
		$time = FunctionApp::getUserKey($appid, $userid, $keytime);
		$score = FunctionApp::getUserKey($appid, $userid, $key);
		if($score == null) $score = 0;
		if($time == null){
			$time = time() ;
		}else{
			if(time()  - $time > 180 ){ 
				if(self::getRewardForTournament($gameid, $userid, $time, $score)){
					$key_tour = "_tward_" .$gameid;
					FunctionApp::incUserKey($appid, $userid, $key_tour);
				}
				$key_last = "_lscore_" .$gameid;
				$key_lasttime = "_lsctime_" .$gameid;
				FunctionApp::setUserKey($appid, $userid, $key_last, $score);
				FunctionAPP::setUserKey($appid, $userid, $key_lasttime, $time);
				$time = time() ;
				$score = 0;
				FunctionApp::setUserKey($appid, $userid, $key, 0);
				FunctionApp::setUserKey($appid, $userid, $keytime, $time);				
			}
		}		
		$friends = FunctionSession::getFriends();
		$result = array();
		$result[] = array("id"=>$userid,"name"=>FunctionData::getDisplayNameOfId($userid),"score"=>$score);
		if($friends != null){
			$fids = $friends->getFriendsID();
			if(!is_array($fids) || count($fids) < 1 ){
				return null;
			}
			$check_tour = ($time - ($time % 180 ))/ 180 ;
			foreach($fids as $fid){
				$ftime = FunctionApp::getUserKey($appid, $fid, $keytime);
				if($ftime == null){
					continue;
				}
				$fturn = ($ftime - ($ftime % 180 ))/ 180 ;
				$score_key = $key;
				if($fturn != $check_tour){
					$ftime = FunctionApp::getUserKey($appid, $fid, $key_lasttime);
					if($ftime == null) continue;
					$fturn = ($ftime - ($ftime % 180 ))/ 180 ;
					$score_key = $key_last;
					if($fturn != $check_tour) continue;
				}
				$fscore = FunctionApp::getUserKey($appid, $fid, $score_key);
				$result[] = array("id"=>$fid,"name"=>FunctionData::getDisplayNameOfId($fid),"score"=>$fscore);
			}
			return $result;
		}else {
		}
	}
	static function getTournamentRewardOfUser($gameid, $userid){
		$appid = DataGameManager::getAppID();
		$key_tour = "_tward_" .$gameid;
		$reward = FunctionApp::getUserKey($appid, $userid, $key_tour);
		if($reward != null && $reward > 0){
			FunctionApp::setUserKey($appid, $userid, $key_tour, 0);
			return $reward;		
		}
		return 0;
	}
}
?>